home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / lisp / eulisp / feel0_89.lha / Feel / Src / streams.c < prev    next >
C/C++ Source or Header  |  1993-07-16  |  17KB  |  774 lines

  1. /* 
  2.   * nprint.c
  3.   * Revised printing routines for feel
  4.   * Idea is that a stream should only handle 
  5.   * its raw type (eg strings, or bytesequences)
  6.   */
  7.  
  8. #include <stdio.h>
  9. #include <ctype.h>
  10.  
  11. #ifndef SEEK_SET /* For non-conforming defs of seek */
  12. #define SEEK_SET 0
  13. #endif 
  14.  
  15. #include "funcalls.h"
  16. #include "defs.h"
  17. #include "structs.h"
  18. #include "error.h"
  19. #include "global.h"
  20. #include "allocate.h"
  21. #include "modboot.h"
  22. #include "calls.h"
  23.  
  24. #include "streams.h"
  25. #include "reader.h"
  26. #include "ngenerics.h"
  27.  
  28. #if 0 /* debugging ..*/
  29. (fprintf(stderr, "File: %x",*((FILE **) stringof(fobj))))
  30. #endif
  31.  
  32. #define fpof(fobj)   (*((FILE **) stringof(fobj)))
  33.  
  34. #define fpof1(fobj)   (*((FILE **) stringof(fobj)))
  35.  
  36. /* Standard Streams */
  37.  
  38. LispObject std_streams;
  39.  
  40. EUFUN_0(Fn_std_streams)
  41. {
  42.   return std_streams;
  43. }
  44. EUFUN_CLOSE
  45.  
  46. /* File operations */
  47.  
  48. static EUFUN_2(Fn_fopen,name,mode)
  49.   LispObject ans;
  50.   FILE *fp;
  51.   
  52.   fp=fopen(stringof(name),stringof(mode));
  53.   if (fp==NULL)
  54.     CallError(stacktop,"Could not open file",name,NONCONTINUABLE);
  55.   ans=allocate_string(stacktop,"",sizeof(FILE*));
  56.   fpof1(ans)=fp;
  57.   return ans;
  58. }
  59. EUFUN_CLOSE 
  60.  
  61. static EUFUN_2(Fn_popen,name,mode)
  62. {
  63. #ifdef HAS_POPEN
  64.   LispObject ans;
  65.   FILE *fp;
  66.   
  67.   fp=popen(stringof(name),stringof(mode));
  68.   if (fp==NULL)
  69.     CallError(stacktop,"Could not open pipe",name,NONCONTINUABLE);
  70.   ans=allocate_string(stacktop,"",sizeof(FILE*));
  71.   fpof1(ans)=fp;
  72.   return ans;
  73. #else
  74.   CallError(stacktop,"popen: no pipes here",nil,NONCONTINUABLE);
  75.   return nil;
  76. #endif
  77. }
  78. EUFUN_CLOSE
  79.   
  80. static EUFUN_1(Fn_reopen,what)
  81. {
  82.   LispObject ans;
  83.   FILE *fp;
  84.  
  85.   switch (intval(what))
  86.     {
  87.     case 0:
  88.       fp=stdin;
  89.       break;
  90.     case 1:
  91.       fp=stdout;
  92.       break;
  93.     case 2:
  94.       fp=stderr;
  95.       break;
  96.     default:
  97.       return nil;
  98.     }
  99.  
  100.   ans=allocate_string(stacktop,"",sizeof(FILE*));
  101.   fpof1(ans)=fp;
  102.   
  103.   return ans;
  104. }
  105. EUFUN_CLOSE
  106.  
  107. static EUFUN_2(Fn_seek,stream,offset)
  108. {
  109.   int ret;
  110.   
  111.   if (!is_fixnum(offset))
  112.     CallError(stacktop,"seek[file]: Invalid offset",offset,NONCONTINUABLE);
  113.  
  114.   ret=fseek(fpof(stream),intval(offset),SEEK_SET);
  115.   
  116.   if (ret)
  117.     CallError(stacktop,"seek[file]: Seek failed",offset,NONCONTINUABLE);
  118.   
  119. #ifdef WITH_FUDGE
  120.   {
  121.     extern void yy_reset_stream(FILE *);
  122.     yy_reset_stream(fpof(stream));            
  123.   }
  124. #endif
  125.  
  126.   return lisptrue;
  127. }
  128. EUFUN_CLOSE
  129.   
  130. static EUFUN_1(Fn_tell,stream)
  131. {
  132.   int ret;
  133.  
  134.   ret=ftell(fpof(stream));
  135.   
  136.   if (ret<0)
  137.     CallError(stacktop,"tell[file]: Tell failed",stream,NONCONTINUABLE);
  138.  
  139.   return(allocate_integer(stacktop,ret));
  140. }
  141. EUFUN_CLOSE
  142.   
  143. static EUFUN_1(Fn_flush,stream)
  144. {
  145.   int ret;
  146.  
  147.   ret=fflush(fpof(stream));
  148.   if (ret!=0)
  149.     {    
  150. #if 0 /* Stardents sometimes return non-zero on flush! */
  151.       print_string(stacktop,StdOut(),"Ouch--flush failure\n");
  152.       EUCALL_3(generic_apply_2,generic_prin,stream,StdOut());
  153. #endif
  154.       return nil;
  155.  
  156.     }    
  157. /*CallError(stacktop,"flush[file]: flush failed",stream,NONCONTINUABLE);*/
  158.   
  159.   return lisptrue;
  160. }
  161. EUFUN_CLOSE
  162.   
  163. /* Bug: Pipes should call pclose, not fclose! */
  164.  
  165. static EUFUN_1(Fn_close,stream)
  166.   int ret;
  167.   
  168.   ret=reader_fclose(stacktop,fpof(stream));
  169.   if (ret!=0)    
  170.     {
  171.       perror("close");
  172.       CallError(stacktop,"close[file]: close failed",stream,NONCONTINUABLE);
  173.     }
  174.   
  175.   return lisptrue;
  176. }
  177. EUFUN_CLOSE
  178.   
  179. /* Output to a stream */
  180.  
  181. /* This can handle both strings and characters */
  182.   
  183. static EUFUN_2(Fn_put,stream,ob)
  184. {
  185.   if (is_string(ob))
  186.     {
  187.       fputs(stringof(ob),fpof(stream));
  188.       return ob;
  189.     }
  190.   
  191.   if (is_char(ob))
  192.     {
  193.       fputc(ob->CHAR.code,fpof(stream));
  194.       return ob;
  195.     }
  196.   
  197.   CallError(stacktop,"put[file]: Invalid object type",classof(ob),NONCONTINUABLE);
  198.   return nil; /* Not ever */
  199. }
  200. EUFUN_CLOSE
  201.  
  202.   
  203. static EUFUN_2(Fn_prin_fixnum,n,stream)
  204. {    
  205.   char buf[32];
  206.   
  207.   sprintf(buf,"%d",intval(n));
  208.   return(print_string(stacktop,stream,buf));
  209. }    
  210. EUFUN_CLOSE
  211.   
  212. /* Callbacks */
  213. LispObject generic_prin,generic_write, generic_flush;
  214. static LispObject generic_output,generic_read;
  215. LispObject format_specifiers;
  216. static LispObject Fn_prin_list(LispObject *);
  217.  
  218. EUFUN_2(Fn_print,ob,stream)
  219. {
  220.   if (stream==nil)
  221.     stream=StdOut();
  222.   else
  223.     stream=stream;
  224.   
  225.   STACK_TMP(stream);
  226.   generic_apply_2(stacktop,generic_prin,ob,stream);
  227.   UNSTACK_TMP(stream);
  228.   print_string(stacktop,stream,"\n");
  229.   
  230.   return ARG_0(stackbase);
  231. }
  232. EUFUN_CLOSE
  233. /* Ops coded in 'C' for efficiency */
  234. /* Only handles a few cases --- needed to bootstrap */
  235. static EUFUN_2(Fn_prin_object,ob,stream)
  236. {
  237.   switch(typeof(ob))
  238.     {
  239.     case TYPE_CONS:    
  240.       EUCALL_2(Fn_prin_list,ob,stream);
  241.       break;
  242.  
  243.     case TYPE_INT:
  244.       EUCALL_2(Fn_prin_fixnum,ob,stream);
  245.       break;
  246.  
  247.     case TYPE_STRING:
  248.       print_string(stacktop,stream,stringof(ob));
  249.       break;
  250.       
  251.     case TYPE_SYMBOL:
  252.       print_string(stacktop,stream,stringof(ob->SYMBOL.pname));
  253.       break;
  254.  
  255.     default:
  256.       {
  257.     char buf[32];
  258.     print_string(stacktop,stream,"#<");
  259.     print_string(stacktop,ARG_1(stackbase),stringof(classof(ARG_0(stackbase))->CLASS.name->SYMBOL.pname));
  260.     sprintf(buf,": %x>",(unsigned long) ob);
  261.     print_string(stacktop,ARG_1(stackbase),buf);
  262.       }
  263.       break;
  264.  
  265.     }    
  266.  
  267.   return ARG_0(stackbase);
  268. }
  269. EUFUN_CLOSE
  270.  
  271. static EUFUN_2(Fn_prin_list,form,stream)
  272. {
  273.   stacktop++;
  274.   ARG_2(stackbase)=form;
  275.   if (typeof(stream)==TYPE_STREAM)
  276.     {
  277.       putc('(',fpof(stream));
  278.       generic_apply_2(stacktop,generic_prin, CAR(form), ARG_1(stackbase));
  279.       form = ARG_0(stackbase);
  280.  
  281.       form=CDR(form);
  282.       while (is_cons(form))
  283.     {
  284.       putc(' ',fpof(ARG_1(stackbase)));
  285.       ARG_0(stackbase) = form;
  286.       generic_apply_2(stacktop,generic_prin, CAR(form), ARG_1(stackbase));
  287.       form = ARG_0(stackbase);
  288.       form=CDR(form);
  289.     }
  290.       if (form!=nil)
  291.     {
  292.       fputs(" . ",fpof(ARG_1(stackbase)));
  293.       generic_apply_2(stacktop,generic_prin, form, ARG_1(stackbase));
  294.     }
  295.       putc('(',fpof(ARG_1(stackbase)));
  296.     }
  297.   else
  298.     {
  299.       LispObject s; /* Temporary for holding bits of string */
  300.       
  301.       s=allocate_string(stacktop,"(",3);
  302.       STACK_TMP(s);
  303.       generic_apply_2(stacktop,generic_prin,s,ARG_1(stackbase));
  304.       form=ARG_0(stackbase);
  305.       generic_apply_2(stacktop,generic_prin,CAR(form),ARG_1(stackbase));
  306.       
  307.       UNSTACK_TMP(s);
  308.       strcpy(stringof(s)," ");
  309.       form=CDR(ARG_0(stackbase));
  310.       STACK_TMP(s);
  311.       while (is_cons(form))
  312.     {
  313.       UNSTACK_TMP(s);
  314.       STACK_TMP(s);
  315.       ARG_0(stackbase)=form;
  316.       generic_apply_2(stacktop,generic_prin,s,ARG_1(stackbase));      
  317.       form=ARG_0(stackbase);
  318.       generic_apply_2(stacktop,generic_prin,CAR(form),ARG_1(stackbase));
  319.       form=CDR(ARG_0(stackbase));
  320.     }
  321.       UNSTACK_TMP(s);
  322.       STACK_TMP(s);
  323.       if (form!=nil)
  324.     {
  325.       strcpy(stringof(s)," . ");
  326.       ARG_0(stackbase)=form;
  327.       generic_apply_2(stacktop,generic_prin,s,ARG_1(stackbase));
  328.       form=ARG_0(stackbase);
  329.       generic_apply_2(stacktop,generic_prin,form,ARG_1(stackbase));
  330.     }
  331.       UNSTACK_TMP(s);
  332.       strcpy(stringof(s),")");
  333.       generic_apply_2(stacktop,generic_prin,s,ARG_1(stackbase));
  334.     }
  335.   return ARG_0(stackbase);
  336. }    
  337. EUFUN_CLOSE
  338.  
  339. /* HACK: if stream is nil, use stdout. if t, use sederr */
  340. LispObject print_string(LispObject *stacktop,LispObject stream, char *ptr)
  341. {
  342.   if (typeof(stream)==TYPE_STREAM)
  343.     fputs(ptr,fpof(stream));
  344.   else if (stream==nil)
  345.     fputs(ptr,stdout);
  346.   else if (stream==lisptrue)
  347.     fputs(ptr,stderr);
  348.   else
  349.     {
  350.       LispObject s;
  351.       STACK_TMP(stream);
  352.       s=allocate_string(stacktop,ptr,strlen(ptr));
  353.       UNSTACK_TMP(stream);
  354.       generic_apply_2(stacktop,generic_prin,s,stream);
  355.     }
  356.   return nil;
  357. }
  358.  
  359. /* Format operations */
  360.  
  361. /* Getting at callbacks */
  362.  
  363. static EUFUN_0(Fn_std_formatters)
  364. {
  365.   return format_specifiers;
  366. }
  367. EUFUN_CLOSE
  368.  
  369. #define FORMATSIZE 200
  370. /* Internal format --- can't handle format nil, t, etc */
  371. static EUFUN_3(Fn_iformat,stream,fmt,args)
  372. {
  373.   char buf[FORMATSIZE];
  374.   char *next,*fmtptr,c;
  375.   int i,j,done=FALSE;
  376.   LispObject add_arg=nil;
  377.  
  378.   /* Check arguments */
  379.   
  380.   /* wait until we get a tilde */
  381.   
  382.   j=0;
  383.   
  384.   while (!done)
  385.     {
  386.       i=0;
  387.       while ( (c=stringof(fmt)[j])!='\0'
  388.          && c!='~')
  389.     {
  390.       buf[i++]=c;
  391.       j++;
  392.       if (i==FORMATSIZE-1)
  393.         {    
  394.           print_string(stacktop,stream,buf);
  395.           fmt=ARG_1(stackbase);
  396.           stream=ARG_0(stackbase);
  397.           i=0;
  398.         }
  399.     }
  400.   
  401.       buf[i]='\0';
  402.       if (i!=0)
  403.     print_string(stacktop,stream,buf);
  404.       fmt=ARG_1(stackbase);
  405.       /* We have to be careful here as fmt may move */
  406.  
  407.       if (c=='\0')
  408.     done=TRUE;
  409.       else
  410.     {
  411.       int n1,n2;
  412.       LispObject tmp=nil;
  413.  
  414.       j++;
  415.       fmtptr=&stringof(fmt)[j];
  416.       n1=strtol(fmtptr,&next,10);
  417.       if (next!=fmtptr)
  418.         {
  419.           if (*next=='.')
  420.         {
  421.           fmtptr=next+1;
  422.           n2=strtol(fmtptr,&next,10);
  423.           if (next==fmtptr)
  424.             CallError(stacktop,"format: No number after dot",fmt,NONCONTINUABLE);
  425.           
  426.           tmp=allocate_integer(stacktop,n2);
  427.         }
  428.           j=next-stringof(fmt);
  429.           add_arg=allocate_integer(stacktop,n1);
  430.           add_arg=EUCALL_2(Fn_cons,add_arg,tmp);
  431.         }
  432.       fmt=ARG_1(stackbase);
  433.       if (stringof(fmt)[j]=='\0')
  434.         done=TRUE;
  435.       else
  436.         {
  437.           LispObject fn;
  438.  
  439.           fn=vref(format_specifiers,stringof(fmt)[j]);
  440.           if (fn==nil)
  441.         CallError(stacktop,"Format: unknown format specifier",fmt,NONCONTINUABLE);
  442.       
  443.           args=EUCALL_4(apply3,fn,ARG_0(stackbase),ARG_2(stackbase),add_arg);
  444.           ARG_2(stackbase)=args;
  445.           j++;
  446.           fmt=ARG_1(stackbase);
  447.           stream=ARG_0(stackbase);
  448.         }
  449.     }
  450.     } /* end while(1) */
  451.   return nil;
  452. }
  453. EUFUN_CLOSE
  454.  
  455. /* Format functions */
  456. #ifndef N_BITS_IN_CHAR
  457. #define N_BITS_IN_CHAR 8
  458. #endif
  459.  
  460. #define BIGBIN sizeof(int)*N_BITS_IN_CHAR
  461. static EUFUN_3(Fn_format_b,stream,args,add_args)
  462. {
  463.   char buf[BIGBIN+1];
  464.   int n;
  465.   char *ptr;
  466.   
  467.   if (!is_fixnum(CAR(args)))
  468.     CallError(stacktop,"format: not an integer",CAR(args),NONCONTINUABLE);
  469.         
  470.   n=intval(CAR(args));
  471.   ptr=buf+BIGBIN;
  472.   buf[BIGBIN+1]=0;
  473.  
  474.   while(n!=0)
  475.     {
  476.       *ptr-- = (n&1)+'0';
  477.       n>>=1;
  478.     }
  479.         
  480.   print_string(stacktop,stream,ptr+1);
  481.   
  482.   return CDR(args);
  483. }
  484. EUFUN_CLOSE
  485.  
  486. static EUFUN_3(Fn_format_u,stream,args,add_args)
  487. {
  488.   char buf[64];
  489.   
  490.   sprintf(buf,"0x%x",CAR(args));
  491.   print_string(stacktop,stream,buf);
  492.   
  493.   return CDR(args);
  494. }
  495. EUFUN_CLOSE
  496.  
  497.  
  498. static EUFUN_3(Fn_format_e,stream,args,add_args)
  499. {
  500.   char buf[64],fmtbuf[40];
  501.   double val;
  502.  
  503.   if (is_float(CAR(args)))
  504.     val=CAR(args)->FLOAT.fvalue;
  505.   else if (is_fixnum(CAR(args)))
  506.     val=(double)intval(CAR(args));
  507.   else
  508.     CallError(stacktop,"format: expected a number",CAR(args),NONCONTINUABLE);
  509.  
  510.   if (add_args=nil)
  511.     strcpy(fmtbuf,"%f");
  512.   else if (CDR(add_args)==nil)
  513.     sprintf(fmtbuf,"%%%df",intval(CAR(add_args)));
  514.   else
  515.     sprintf(fmtbuf,"%%%d.%de",intval(CAR(add_args)),intval(CAR(CDR(add_args))));
  516.   
  517.   sprintf(buf,fmtbuf,val);
  518.   print_string(stacktop,stream,buf);
  519.   
  520.   return nil;
  521. }
  522. EUFUN_CLOSE
  523.  
  524. static EUFUN_3(Fn_format_f,stream,args,add_args)
  525. {
  526.   char buf[64],fmtbuf[40];
  527.   double val;
  528.  
  529.   if (is_float(CAR(args)))
  530.     val=CAR(args)->FLOAT.fvalue;
  531.   else if (is_fixnum(CAR(args)))
  532.     val=(double)intval(CAR(args));
  533.   else
  534.     CallError(stacktop,"format: expected a number",CAR(args),NONCONTINUABLE);
  535.  
  536.   if (add_args=nil)
  537.     strcpy(fmtbuf,"%f");
  538.   else if (CDR(add_args)==nil)
  539.     sprintf(fmtbuf,"%%%df",intval(CAR(add_args)));
  540.   else
  541.     sprintf(fmtbuf,"%%%d.%df",intval(CAR(add_args)),intval(CAR(CDR(add_args))));
  542.   
  543.   sprintf(buf,fmtbuf,val);
  544.   print_string(stacktop,stream,buf);
  545.   
  546.   return nil;
  547. }
  548. EUFUN_CLOSE
  549.  
  550. static EUFUN_3(Fn_format_g,stream,args,add_args)
  551. {
  552.   char buf[64],fmtbuf[40];
  553.   double val;
  554.  
  555.   if (is_float(CAR(args)))
  556.     val=CAR(args)->FLOAT.fvalue;
  557.   else if (is_fixnum(CAR(args)))
  558.     val=(double)intval(CAR(args));
  559.   else
  560.     CallError(stacktop,"format: expected a number",CAR(args),NONCONTINUABLE);
  561.  
  562.   if (add_args=nil)
  563.     strcpy(fmtbuf,"%f");
  564.   else if (CDR(add_args)==nil)
  565.     sprintf(fmtbuf,"%%%df",intval(CAR(add_args)));
  566.   else
  567.     sprintf(fmtbuf,"%%%d.%dg",intval(CAR(add_args)),intval(CAR(CDR(add_args))));
  568.   
  569.   sprintf(buf,fmtbuf,val);
  570.   print_string(stacktop,stream,buf);
  571.   
  572.   return nil;
  573. }
  574. EUFUN_CLOSE
  575.  
  576. /* Input operations */
  577.  
  578. EUFUN_1(Fn_read_char,stream)
  579. {
  580.   int c;
  581.  
  582.   c=fgetc(fpof(stream));
  583.   
  584.   if (c==0)
  585.     return q_eof;
  586.   else
  587.     {
  588. #ifdef WITH_FUDGE
  589.       {
  590.     extern void yy_reset_stream(FILE *);
  591.     yy_reset_stream(fpof(stream));
  592.       }
  593. #endif
  594.       return allocate_char(stacktop,c);
  595.     }
  596. }
  597. EUFUN_CLOSE
  598.  
  599. EUFUN_2(Fn_ungetc,stream,c)
  600. {
  601.   ungetc(c->CHAR.code,fpof(stream));
  602.  
  603. #ifdef WITH_FUDGE
  604.       {
  605.     extern void yy_reset_stream(FILE *);
  606.     yy_reset_stream(fpof(stream));
  607.       }
  608. #endif
  609.   
  610.   return lisptrue;
  611. }
  612. EUFUN_CLOSE
  613. /* Read chars until we hit whitespace */
  614. #define READBUFSZ 10
  615. EUFUN_1(Fn_read_line,stream)
  616. {        
  617.   LispObject tmp=nil,oldtmp;
  618.   char buf[READBUFSZ];
  619.   int len=0,i=0,c;
  620.   
  621.   while ((c=getc(fpof(stream)))!=EOF)
  622.     {    
  623.       buf[i]=c;
  624.       i++;
  625.       if (i==READBUFSZ)
  626.     {    /* Grab more... */
  627.       if (tmp==nil)
  628.         {
  629.           tmp=allocate_string(stacktop,buf,READBUFSZ);
  630.         }
  631.       else
  632.         {    
  633.           oldtmp=tmp;
  634.           tmp=allocate_string(stacktop,stringof(oldtmp),len+READBUFSZ);
  635.           strncpy(stringof(tmp)+len,buf,READBUFSZ);
  636.         }
  637.       len+=READBUFSZ;
  638.       i=0;
  639.       stream=ARG_0(stackbase);
  640.     }
  641.  
  642.       if (c=='\n')
  643.     break;
  644.     }    
  645.   
  646.   if (len+i==0)
  647.     return q_eof;
  648.  
  649.   buf[i]='\0';
  650.  
  651.   if (tmp==nil)
  652.     return allocate_string(stacktop,buf,i);
  653.   else
  654.     {
  655.       oldtmp=tmp;
  656.       tmp=allocate_string(stacktop,stringof(oldtmp),len+i);
  657.       strcpy(stringof(tmp)+len,buf);
  658.       return tmp;
  659.     }
  660. }
  661. EUFUN_CLOSE
  662.  
  663. EUFUN_1(Fn_read,stream)
  664. {
  665.   if (stream==nil) 
  666.     return(sys_read(stacktop,stdin));
  667.   else
  668.     return generic_apply_1(stacktop,generic_read,stream);
  669. }
  670. EUFUN_CLOSE
  671.  
  672. EUFUN_1(Fn_fread,stream)
  673. {
  674.  return(sys_read(stacktop,fpof(stream)));
  675. }
  676. EUFUN_CLOSE
  677.  
  678. EUFUN_1(Fn_escape_id_p,s)
  679. {
  680.   extern int escaped_id(char *);
  681.  
  682.   return (escaped_id(stringof(s))
  683.       ? lisptrue : nil);
  684. }
  685. EUFUN_CLOSE
  686.  
  687. #define NSTREAMS_ENTRIES 31
  688.  
  689. MODULE Module_nstreams;
  690. LispObject Module_nstreams_values[NSTREAMS_ENTRIES];
  691.  
  692. void initialise_streams(LispObject *stacktop)
  693. {
  694. #ifdef WITH_FUDGE
  695.   initialise_fudge();
  696. #endif
  697.  
  698.   open_module(stacktop,
  699.           &Module_nstreams,    
  700.           Module_nstreams_values,
  701.           "streams",
  702.           NSTREAMS_ENTRIES);
  703.   
  704.   /* For bootstrapping, we use nil, nil and t for stdin, etc.
  705.      These are re-hacked later */
  706.   MakeStdStreams();
  707.   StdIn()=nil;
  708.   StdOut()=nil;
  709.   StdErr()=lisptrue;
  710.   
  711.   q_eof=allocate_char(stacktop,256);
  712.   add_root(&q_eof);
  713.  
  714.   format_specifiers=allocate_vector(stacktop,256);
  715.   add_root(&format_specifiers);
  716.  
  717.   make_module_entry(stacktop,"*eof*",q_eof);
  718.  
  719.   generic_prin
  720.     = make_module_generic(stacktop,"generic-prin",2);
  721.   add_root(&generic_prin);
  722.  
  723.   generic_write
  724.     = make_module_generic(stacktop,"generic-write",2);
  725.   add_root(&generic_write);
  726.  
  727.   generic_output
  728.     = make_module_generic(stacktop,"output",2);
  729.   add_root(&generic_output);
  730.  
  731.   generic_flush
  732.     = make_module_generic(stacktop,"flush",1);
  733.   add_root(&generic_flush);
  734.  
  735.   generic_read
  736.     = make_module_generic(stacktop,"generic-read",1);
  737.   add_root(&generic_read);
  738.  
  739.   (void) make_module_function(stacktop,"std-streams",Fn_std_streams,0);
  740.   (void) make_module_function(stacktop,"fopen",Fn_fopen,2);
  741.   (void) make_module_function(stacktop,"fpopen",Fn_popen,2);
  742.   (void) make_module_function(stacktop,"freopen",Fn_reopen,1);
  743.   (void) make_module_function(stacktop,"fseek",Fn_seek,2);
  744.   (void) make_module_function(stacktop,"ftell",Fn_tell,1);
  745.   (void) make_module_function(stacktop,"fflush",Fn_flush,1);
  746.   (void) make_module_function(stacktop,"fclose",Fn_close,1);
  747.   (void) make_module_function(stacktop,"fput",Fn_put,2);
  748.  
  749.   (void) make_module_function(stacktop,"print-fixnum",Fn_prin_fixnum,2);
  750.   (void) make_module_function(stacktop,"print-list",Fn_prin_list,2);
  751.   (void) make_module_function(stacktop,"prin-object",Fn_prin_object,2);
  752.  
  753.   (void) make_module_function(stacktop,"std-formatters",Fn_std_formatters,0);
  754.   (void) make_module_function(stacktop,"internal-format",Fn_iformat,3);
  755.   (void) make_module_function(stacktop,"b-formatter",Fn_format_b,3);
  756.   (void) make_module_function(stacktop,"e-formatter",Fn_format_e,3);
  757.   (void) make_module_function(stacktop,"f-formatter",Fn_format_f,3);
  758.   (void) make_module_function(stacktop,"g-formatter",Fn_format_g,3);
  759.   (void) make_module_function(stacktop,"u-formatter",Fn_format_u,3);
  760.  
  761.   (void) make_module_function(stacktop,"read",Fn_read,1);
  762.   (void) make_module_function(stacktop,"fread",Fn_fread,1);
  763.   (void) make_module_function(stacktop,"fread-line",Fn_read_line,1);
  764.   (void) make_module_function(stacktop,"fread-char",Fn_read_char,1);
  765.   (void) make_module_function(stacktop,"fungetc",Fn_ungetc,2);
  766.  
  767.   (void) make_module_function(stacktop,"escaped-id-p",Fn_escape_id_p,1);
  768.   
  769.   close_module();
  770. }
  771.  
  772.